package cn.wolfcode.shop.cloud.service.impl;

import cn.wolfcode.shop.cloud.SeckillServerApp;
import cn.wolfcode.shop.cloud.common.BusinessException;

import cn.wolfcode.shop.cloud.common.Result;
import cn.wolfcode.shop.cloud.domain.Good;
import cn.wolfcode.shop.cloud.domain.SeckillGood;
import cn.wolfcode.shop.cloud.feign.GoodsFeignApi;
import cn.wolfcode.shop.cloud.mapper.SeckillGoodMapper;

import cn.wolfcode.shop.cloud.redis.RedisService;
import cn.wolfcode.shop.cloud.redis.SecKillKeyPrefix;
import cn.wolfcode.shop.cloud.service.ISeckillGoodService;
import cn.wolfcode.shop.cloud.util.SeckillCodeMsg;
import cn.wolfcode.shop.cloud.vo.SeckillGoodVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;


@Service
class SeckillGoodServiceImpl implements ISeckillGoodService {

    @Autowired
    private RedisService redisService;
    @Autowired
    private SeckillGoodMapper seckillGoodMapper;
    @Autowired
    private GoodsFeignApi goodsFeignApi;
    @Override
    public List<SeckillGoodVO> query() {
        //首先查询秒杀商品的数据
        List<SeckillGood> seckillGoods = seckillGoodMapper.querySeckillGooods();
        //把商品id封装到一个set集合中
        return common(seckillGoods);
    }

    /*
    抽取公共的代码
     */
public  List<SeckillGoodVO> common(List<SeckillGood> seckillGoods){
    HashSet<Long> goodIds = new HashSet<>();
    for (SeckillGood seckillGood : seckillGoods) {
        goodIds.add(seckillGood.getGoodId());
    }
    //把这个set集合放到一个list集合中方便for循环遍历
    ArrayList<Long> ids = new ArrayList<>(goodIds);
    //到远程商品服务中去拿商品的数据
    Result<List<Good>> result = goodsFeignApi.queryByIds(ids);
    if (result==null||result.getCode()!=200){
        throw new BusinessException(SeckillCodeMsg.PRODUCT_OPT);
    }
    List<Good> goods=result.getData();
    //把goods放入到map中key的是good的id，value=good对象
    HashMap<Long, Good> map = new HashMap<>();
    for (Good good : goods) {
        map.put(good.getId(),good);
    }
    List<SeckillGoodVO> goodVOS = new ArrayList<>();
    //内存当中进行集合操作，最终要返回一个List<SeckillGoodVO>
    for (SeckillGood seckillGood : seckillGoods) {
        SeckillGoodVO seckillGoodVO = new SeckillGoodVO();
        //拿到商品id
        Good good = map.get(seckillGood.getGoodId());
        seckillGoodVO.setGoodDetail(good.getGoodDetail());
        seckillGoodVO.setGoodImg(good.getGoodImg());
        seckillGoodVO.setGoodName(good.getGoodName());
        seckillGoodVO.setGoodPrice(good.getGoodPrice());
        seckillGoodVO.setGoodStock(good.getGoodStock());
        seckillGoodVO.setGoodTitle(good.getGoodTitle());
        seckillGoodVO.setEndDate(seckillGood.getEndDate());
        seckillGoodVO.setSeckillPrice(seckillGood.getSeckillPrice());
        seckillGoodVO.setStartDate(seckillGood.getStartDate());
        seckillGoodVO.setGoodStock(seckillGood.getStockCount());
        seckillGood.setId(seckillGood.getId());
        goodVOS.add(seckillGoodVO);

    }
    return goodVOS;
}
    @Override
    public SeckillGoodVO queryById(Long seckillId) {
        SeckillGood seckillGood = seckillGoodMapper.findById(seckillId);
        List<SeckillGood> list = new ArrayList<>();
        list.add(seckillGood);

        List<SeckillGoodVO> vos = common(list);
        return vos.get(0);
    }

    @Override
    public int decrCount(Long seckillId) {

        return seckillGoodMapper.decrCount(seckillId);
    }

    @Override
    public SeckillGoodVO queryByIdCache(Long seckillId) {
        return redisService.hget(SecKillKeyPrefix.SECKILL_GOOD_HASH,"",seckillId+"",SeckillGoodVO.class);
    }

    @Override
    public List<SeckillGoodVO> queryCache() {
        Map<String, SeckillGoodVO> stringSeckillGoodVOMap = redisService.hgetAll(SecKillKeyPrefix.SECKILL_GOOD_HASH, "", SeckillGoodVO.class);
        //可以把map封装成list
        return new ArrayList<SeckillGoodVO>(stringSeckillGoodVOMap.values());
    }

    @Override
    public void incrCount(Long seckillId) {
    seckillGoodMapper.incrCount(seckillId);
    }

    @Override
    public void syncRedisCount(Long goodId) {
    //重新把数据库的库存设置进去
        SeckillGoodVO seckillGoodVO=queryById(goodId);
        redisService.set(SecKillKeyPrefix.SECKILL_STOCK_COUNT,""+goodId,seckillGoodVO.getStockCount());
    }
}
